﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace Nate_sRoguelikeGame
{
    static class Extensions
    {
        public static int GetArea(this Rectangle rectangle)
        {
            return rectangle.Width*rectangle.Height;
        }
        
    }
    class Utilities
    {
        
        public static string GetInputLine(string message, bool carriageReturn = false)
        {
            if (carriageReturn)
                Console.WriteLine(message);
            else
                Console.Write(message);
            return Console.ReadLine().Trim();
        }

        public static char GetInputKeyChar(string message, bool carriageReturn = false)
        {
            if (carriageReturn)
                Console.WriteLine(message);
            else
                Console.Write(message);
            Console.SetCursorPosition(0, 0);

            return Console.ReadKey(true).KeyChar;
        }

        public static char GetInputKeyChar(string message, char[] allowedKeys, bool displayAvailableKeys = true, bool isCaseSensitive = false, bool carriageReturn = false)
        {
            char key = GetInputKeyChar(String.Format("{0} ({1})", message, String.Concat(allowedKeys)), carriageReturn);
            char matchedKey = isCaseSensitive
                                  ? allowedKeys.Where(c => c == key).FirstOrDefault()
                                  : allowedKeys.Where(c => c.ToString().ToUpper() == key.ToString().ToUpper()).
                                        FirstOrDefault();

            return matchedKey != '\0' ? matchedKey : GetInputKeyChar(message, allowedKeys, carriageReturn);
        }

        /// <summary>
        /// Displays the message and (optionally) the keystrokes allowed;
        /// Returns the user's input.
        /// </summary>
        /// <param name="message">The message to display</param>
        /// <param name="allowedKeys">An array containing all accepted keys. If null or empty, any key is accepted.</param>
        /// <param name="displayAvailableKeys">If true, concats the array of allowed keys and appends them to the message. Ex. "[Message] ([allowedKeys]) "</param>
        /// <returns>The key the user entered.</returns>
        public static ConsoleKeyInfo GetInputKey(Point location, string message, ConsoleKey[] allowedKeys, bool displayAvailableKeys = true)
        {
            Console.SetCursorPosition(0, 0);
                string messageToWrite = displayAvailableKeys
                                            ? String.Format("{0} ({1}) ", message, String.Concat(allowedKeys.Select(k=>k.ToString()).Select(k=>k.Substring(k.Length - 1))))
                                            : message;
                Console.Write(messageToWrite);

                var key = Console.ReadKey(true);
            try
            {
                
                return allowedKeys == null || !allowedKeys.Any() || allowedKeys.Contains(key.Key)
                           ? key
                           : GetInputKey(location, message, allowedKeys, displayAvailableKeys);
            } finally
            {
                Console.SetCursorPosition(location.X, location.Y);
                Console.Write(new String(' ', messageToWrite.Length));
            }
        }
    }
}
